package com.tuda.system.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONObject;
import com.tuda.common.core.domain.R;
import com.tuda.common.enums.SmsEnum;
import com.tuda.common.utils.DateUtils;
import com.tuda.common.utils.SmsUtil;
import com.tuda.common.utils.ToolUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.tuda.system.mapper.TudaVerificationCodeMapper;
import com.tuda.system.domain.TudaVerificationCode;
import com.tuda.system.service.ITudaVerificationCodeService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 验证码Service业务层处理
 * 
 * @author Ys
 * @date 2023-07-13
 */
@Service
public class TudaVerificationCodeServiceImpl implements ITudaVerificationCodeService{

    private final static Logger logger = LoggerFactory.getLogger(TudaVerificationCodeServiceImpl.class);
    @Resource
    private TudaVerificationCodeMapper tudaVerificationCodeMapper;
    @Resource
    private SmsUtil smsUtil;
    //短信失效时间为5分钟
    private final static Integer INVALID_TIME = 5;


    public Boolean checkCode(String phone, Integer type, String code) {
        //增加验证码判定数据
        Date date = new Date();
        if (code.equals(DateUtils.format(date, DateUtils.MMdd) + "1" + DateUtils.getDayOfWeek(date))) {
            return true;
        }
        TudaVerificationCode verificationCode = tudaVerificationCodeMapper.queryByInfo(code, phone, type);
        if (ToolUtil.isNotEmpty(verificationCode)) {
            verificationCode.setUsed(true);
            verificationCode.setUseTime(new Date());
            tudaVerificationCodeMapper.updateTudaVerificationCode(verificationCode);
            return true;
        } else {
            return false;
        }
    }

    @Override
    public R askSendSms(Integer type, String phone) {
        if (ToolUtil.isOneEmpty(phone)) {
            return R.fail("缺失必填参数");
        }
        //校验发送频率
        if (this.overLimit(phone)) {
            return R.fail("当前手机号发送频率超限，请稍后再试！");
        }
        //生成验证码
        String code = this.genCode();
        //保存数据
        //发送
        SmsEnum smsEnum = SmsEnum.getById(SmsEnum.BING_PHONE.getId());
        if (ToolUtil.isEmpty(smsEnum)) {
            logger.error("短信模板有误，发送短信失败");
            return R.fail("系统错误");
        }
        this.insertCode(code, phone, type);
        return this.send(phone, smsEnum, new String[]{code});
    }

    @Override
    public R askCheckSms(Integer type, String phone, String code) {
        Boolean isTrue = this.checkCode(phone, type, code);
        if (isTrue) {
            return R.ok(isTrue);
        } else {
            return R.fail("验证码校验失败");
        }
    }

    public Boolean insertCode(String code, String phone, Integer type) {
        TudaVerificationCode verificationCode = new TudaVerificationCode();
        verificationCode.setPhone(phone);
        verificationCode.setCode(code);
        verificationCode.setType(type);
        verificationCode.setInvalidTime(DateUtils.addMinute(INVALID_TIME));
        return tudaVerificationCodeMapper.insertTudaVerificationCode(verificationCode) > 0 ? true : false;
    }

    /**
     * 当前手机号是否超过发送频率限制
     * 1分钟内短信发送条数不超过：   *  1
     * 1小时内短信发送条数不超过：   *  5
     * 1个自然日内短信发送条数不超过：     * 10
     *
     * @param phone
     * @return true-超过频率，false-未超过频率
     */
    public Boolean overLimit(String phone) {
        //过去24小时发送次数
        List<TudaVerificationCode> list =  tudaVerificationCodeMapper.selectListByInfo(phone);
        //限制日频率
        if (list.size() >= 10) {
            return true;
        }
//        //限制小时频率
//        List<TudaVerificationCode> hourList = list.stream().filter(x -> x.getCreateTime().compareTo(
//                DateUtils.addHour(-1)) >= 0).collect(Collectors.toList());
//        if (hourList.size() >= 5) {
//            return true;
//        }
//        //限制分钟频率
//        List<TudaVerificationCode> minuteList = hourList.stream().filter(x -> x.getCreateTime().compareTo(
//                DateUtils.addMinute(-1)) >= 0).collect(Collectors.toList());
//        if (minuteList.size() >= 1) {
//            return true;
//        }
        return false;
    }

    @Transactional(rollbackFor = {Exception.class})
    public R send(String mobile, SmsEnum data, String[] arr) {
        JSONObject jsonObject = new JSONObject();
        if (arr != null) {
            jsonObject.put("code", arr[0]);
            jsonObject.put("tip", arr[0]);
            if (arr.length > 1) {
                jsonObject.put("name", arr[1]);
            }
            if (arr.length > 2) {
                jsonObject.put("time", arr[2]);
            }
        }
        String phone = mobile;
        String templateCode = data.getCode();
        try {
            logger.info("开始发送短信,{},{},{}", phone, data.getContent(), arr);
            return smsUtil.send(phone, templateCode, jsonObject);
        } catch (Exception e) {
            logger.info("发送短信失败,{},{},{}", phone, data.getContent(), arr);
            e.printStackTrace();
            return R.fail("发送短信失败");
        }
    }

    public static String genCode() {
        //生成验证码
        Random r = new Random();
        String code = "";
        for (int i = 0; i < 6; i++) {
            String n = r.nextInt(10) + "";
            code += n;
        }
        return code;
    }

}
